package yartiss.gui.main;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.Simulation;
import yartiss.engine.simulation.io.DefaultParamsParser;
import yartiss.engine.simulation.scheduling.policies.SchedulingPolicyFactory;
import yartiss.engine.simulation.system.SystemMetrics;
import yartiss.gui.graphics.JEnergyCurve;
import yartiss.gui.graphics.JProcessorDiagram;
import yartiss.gui.graphics.JTaskDiagram;
import yartiss.service.model.DefaultEventsModel;
import yartiss.service.model.IEventsModel;

public class Main {

	public static void main(String[] args) throws Exception {
//		System.out.println("start generating");
//		SystemsGenerator.oldGenerate(Main.class);
//		//int i = 1;
		String file = "results/dam_bug_";
//		//for (int i = 1; i <= 5; i += 1) {
		showTrace(file+1+"_"+1+".sim");
//		//}
	}

	public static void showTrace(String file) throws Exception{
		
		//Simulation sim = new Simulation(DefaultParamsParser.parse(Main.class.getResourceAsStream("/resources/EDF_test1")));
		Simulation sim = new Simulation(DefaultParamsParser.parseXml(Main.class.getResourceAsStream("/resources/EDF_test1.xml")));
		//Simulation sim = new Simulation(DefaultParamsParser.parse("C:/Users/Youn�s/workspace/RTSS/bin/resources/EDF_test1"));
		ISchedulingPolicy policy = SchedulingPolicyFactory
				.getInstance("Laxity_graph_multiproc");		
		//Simulation sim = new Simulation(DefaultParamsParser.parse(Main.class.getResourceAsStream("/resources/graph_laxity_test.xml"), policy, 20, 2));

		
		JFrame window = new JFrame("RTSS-"+file);

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension d = new Dimension(screenSize);
		d.width  *= (5.0 / 6.0);
		d.height *= (5.0 / 6.0);
		window.setBounds((screenSize.width - d.width) / 2, (screenSize.height - d.height) / 2, d.width, d.height);
		window.setPreferredSize(d);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		IEventsModel model = new DefaultEventsModel(sim);
		//EventsTraceModel model = new EventsTraceModel(file);

		final JTaskDiagram td = new JTaskDiagram(model);
		td.setXUnit(10);
		final JEnergyCurve ec = new JEnergyCurve(model);
		
		ec.setSlackEnergyCurveEnabled(true);
		ec.setSlackTimeCurveEnabled(true);
		ec.setMaxLevel((int) sim.getSimulationParameters().getEnergyProfile().getMaxEnergyLevel());
		ec.setMinLevel((int) sim.getSimulationParameters().getEnergyProfile().getMinEnergyLevel());

		//ec.setMaxLevel((int) model.getSimulParameters().getEnergyProfile().getMaxEnergyLevel());
		//ec.setMinLevel((int) model.getSimulParameters().getEnergyProfile().getMinEnergyLevel());

		final JProcessorDiagram pd = new JProcessorDiagram(model);
		
		final JScrollPane sp = new JScrollPane(td);
		sp.setAutoscrolls(true);
		final JScrollPane sp2 = new JScrollPane(ec);
		sp2.setAutoscrolls(true);
		final JScrollPane sp3 = new JScrollPane(pd);
		sp3.setAutoscrolls(true);
		JPanel panel = new JPanel(new GridLayout(2,1));
		//panel.add(sp2);
		panel.add(sp);
		panel.add(sp3);
		panel.setOpaque(true);


		JPanel root = new JPanel(new BorderLayout());
		root.add(panel, BorderLayout.CENTER);
		sp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			@Override
			public void adjustmentValueChanged(AdjustmentEvent e) {
				Point vp1 = sp.getViewport().getViewPosition();
				Point vp2 = sp2.getViewport().getViewPosition();
				vp2.x = vp1.x;
				sp2.getViewport().setViewPosition(vp2);
				sp3.getViewport().setViewPosition(vp2);
			}
		});

		JPanel control = new JPanel();
		BoxLayout bl = new BoxLayout(control, BoxLayout.Y_AXIS);
		control.setLayout(bl);
		final JSlider slider = new JSlider(JSlider.VERTICAL, 1, 20, 10);
		slider.setPaintTicks(true);
		slider.setPaintTrack(true);
		control.add(slider);
		root.add(control, BorderLayout.WEST);
		slider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				ec.setYUnit(slider.getValue());
			}
		});

		final JSlider slider2 = new JSlider(JSlider.HORIZONTAL, 1, 100, 10);
		slider2.setPaintTicks(true);
		slider2.setPaintTrack(true);
		root.add(slider2, BorderLayout.NORTH);

		slider2.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				int xu = slider2.getValue();
				td.setXUnit(xu);
				pd.setXUnit(xu);
				ec.setXUnit(xu);
			}
		});

		final JTextField field = new JTextField(ec.getXAlternate()+"");
		field.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				try {
					int value = Integer.parseInt(field.getText());
					td.setxAlternate(value);
					ec.setXAlternate(value);
				} catch (Exception e2) {}
			}
		});
		control.add(field);

		final JTextField field2 = new JTextField(ec.getyAlternate()+"");
		field2.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				try {
					int value = Integer.parseInt(field2.getText());
					ec.setyAlternate(value);
				} catch (Exception e2) {}
			}
		});
		control.add(field2);

		JButton screenShot = new JButton("SS");
		screenShot.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				Image diag = td.getScreenShot();
				Image curve = ec.getScreenShot();
				BufferedImage img = new BufferedImage(diag.getWidth(null), diag.getHeight(null)+curve.getHeight(null),  BufferedImage.TYPE_INT_ARGB);
				img.getGraphics().drawImage(curve, 0, 0,curve.getWidth(null), curve.getHeight(null), null);
				img.getGraphics().drawImage(diag, 0, curve.getHeight(null), diag.getWidth(null), diag.getHeight(null), null);
				File outputfile = new File("saved.png");
				try {
					ImageIO.write(img, "png", outputfile);
					System.out.println("Screen Shot generated");
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
		control.add(screenShot);
		window.setContentPane(root);
		window.setVisible(true);
		slider.setValue(4);
		slider2.setValue(50);
		sim.simulate();
		
		System.out.println("bp ="+SystemMetrics.FPBusyPeriod(sim.getSimulationParameters().getTaskSet()));
		System.out.println("ebp="+SystemMetrics.FPEnergyBusyPeriod(sim.getSimulationParameters().getTaskSet(), sim.getSimulationParameters().getEnergyProfile().getPowerRate()));

		System.out.println(sim.getStatistics());
	}

}
